package quest.handler
{
import flash.utils.Dictionary;
import flash.utils.getDefinitionByName;

import quest.QuestManager;

import values.quest.QuestGoalValue;
import values.quest.QuestSettingValue;

public class QuestHandler
{
	private static var handlers:Dictionary = new Dictionary(true); /* IQuestGoalHandler */
	private static var logMap:Dictionary = new Dictionary(true); /* Dictionary */
	
	public function QuestHandler()
	{
		QuestResourceItemCollectGoalHandler
		QuestHaveBuildingGoalHandler
	}
	
	public function addTargetQuestGoal(goal:QuestGoalValue):void
	{
		getHandler(goal.template.type).addTargetQuestGoal(goal);
	}
	
	public function removeTargetQuestGoal(goal:QuestGoalValue):void
	{
		if (!hasHandler(goal.template.type)) return;
		var handler:IQuestGoalHandler = getHandler(goal.template.type);
		handler.removeTargetQuestGoal(goal);
		if (handler.isEmpty)
		{
			handler.dispose();
			delete handlers[handler.key];
			
			//remove handler from log map
			var logs:Array = String(QuestSettingValue.questHandlers.(@key == handler.key).@logs).split(",");
			for each (var log:String in logs)
			{
				var map:Dictionary = logMap[log];
				if (!map)
				{
					continue;
				}
				delete map[handler.key];
			}
		}
	}
	
	public function check(type:String, ...args):void
	{
		var map:Dictionary = logMap[type];
		if (!map) return;
		
		var params:Array = [ type ].concat(args);
		for each (var handler:IQuestGoalHandler in map)
		{
			handler.check.apply(handler, params);
		}
	}
	
	private function hasHandler(key:String):Boolean
	{
		return handlers[key] != null;
	}
	
	private function getHandler(key:String):IQuestGoalHandler
	{
		var handler:IQuestGoalHandler = handlers[key];
		if (!handler)
		{
			var ref:String = QuestSettingValue.questHandlers.(@key == key).@class_ref;
			var classRef:Class = getDefinitionByName("quest.handler." + ref) as Class;
			handler = new classRef(QuestManager.instance);
			handlers[key] = handler;
			
			//add handler from log map
			var logs:Array = String(QuestSettingValue.questHandlers.(@key == key).@logs).split(",");
			for each (var log:String in logs)
			{
				var map:Dictionary = logMap[log];
				if (!map)
				{
					map = new Dictionary(true);
					logMap[log] = map;
				}
				map[handler.key] = handler;
			}
		}
		return handler;
	}
	
}
}